package com.thunder.main;

import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;

import com.thunder.component.BackGround;
import com.thunder.component.Bullet;
import com.thunder.component.EnemyFly;
import com.thunder.component.GameReady;
import com.thunder.component.Pause;
import com.thunder.component.Rubbish;
import com.thunder.component.ScoreCounter;
import com.thunder.component.Top;
import com.thunder.component.UserFly;
import com.thunder.utils.Constant;

public class Game extends Frame{
	private static int mGameState;
	private static GameReady gameready;
	private static BackGround background;
	private static UserFly userfly;
	private static Top top;
	private static Pause pause;
	private static ArrayList<Bullet> bullet;
	private static EnemyFly enemyfly;
	private static ArrayList<Rubbish> rubbish;
	private static ScoreCounter scorecounter;
	
	private static int score;
	private static int time;
	
	public static final int Game_Start = 0;
	public static final int Game_Running = 1;
	public static final int Game_Over = 2;
	public static final int Game_Pause = 3;
	
	private static Random re;
	private static Random rr;
	
	
	public Game() {
		initFrame();
		setVisible(true);
		initGame();
	}
	
	public void initFrame() {
		setSize(Constant.FRAME_WIDTH, Constant.FRAME_HEIGHT);
		setTitle(Constant.GAME_TITLE);
		setLocation(Constant.FRAME_X, Constant.FRAME_Y);
		setResizable(false);
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		addKeyListener(new ThunderKeyListener());  
		addMouseListener(new ThunderMouseListener());
	}
	
	class ThunderKeyListener implements KeyListener {
		public void keyPressed(KeyEvent e) {
			int code = e.getKeyCode();
			switch(mGameState) {
				case Game_Start:
					mGameState = Game_Running;
					break;
				case Game_Running:
					RunListener(code);
					break;
				case Game_Over:
					break;
				case Game_Pause:
					break;
			}
		}

		@Override
		public void keyReleased(KeyEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void keyTyped(KeyEvent arg0) {
			// TODO Auto-generated method stub
			
		}
		
		public void RunListener(int code) {
			switch(code) {
				case 39://->
					userfly.move(1);
					break;
				case 37://<-
					userfly.move(-1);
					break;
				case 65://a
					attack();
					break;
			}
		}
	}
	
	class ThunderMouseListener implements MouseListener {

		@Override
		public void mouseClicked(MouseEvent e) {
			// TODO Auto-generated method stub
			int code = e.getButton();
			if(mGameState == Game_Pause) {
				mGameState = Game_Running;
			}
			else if(mGameState == Game_Running) {
				if(10 <= e.getX() && e.getX() <= 60 && 30 <= e.getY() && e.getY() <= 90){
					mGameState = Game_Pause;
				}
				if(480 <= e.getX() && e.getX() <= 600 && 30 <= e.getY() && e.getY() <= 90){
					mGameState = Game_Start;
					initGame();
				}
			}
			else if(mGameState == Game_Over) {
				mGameState = Game_Start;
				initGame();
			}
		}

		@Override
		public void mouseEntered(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseExited(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mousePressed(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseReleased(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}
	}
	public void initGame() {
		re = new Random(1);
		rr = new Random(2);
		
		gameready = new GameReady();
		background = new BackGround();
		userfly = new UserFly();
		top = new Top();
		pause = new Pause();
		bullet = new ArrayList<Bullet>();
		enemyfly = new EnemyFly(Re(re.nextInt()));
		rubbish = new ArrayList<Rubbish>();
		scorecounter = new ScoreCounter();
		
		score = 0;
		time = 0;
		
		setGameState(Game_Start);
		new Thread(() -> {
			while(true) {
				repaint();
				try {
					Thread.sleep(Constant.FPS);
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();
	}
	
	public void attack() {
		Bullet b = new Bullet(userfly.getX(), userfly.getY(), -1);
		bullet.add(b);
	}
	
	
	public void setGameState(int gameState) {
		mGameState = gameState;
	}
	
	public void eattack() {
		if(time % 30  == 0) {
			Bullet b = new Bullet(enemyfly.getX() + 35, 80 + 89, 1); //top + height of enemyfly
			bullet.add(b);
		}
		
	}
	
	private final BufferedImage bufImg = new BufferedImage(Constant.FRAME_WIDTH, Constant.FRAME_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR);
	
	public void update(Graphics g) {
		Graphics buf = bufImg.getGraphics();
		
		if(mGameState == Game_Start) {
			gameready.draw(buf);
		}
		else {
			background.draw(buf);
			userfly.draw(buf);
			for(int i = 0; i < bullet.size(); i++) {
				Bullet b = (Bullet)bullet.get(i);
				if(mGameState != Game_Pause) {
					b.move();
				}
				b.draw(buf);
			}
			if(mGameState == Game_Pause) {
				pause.draw(buf);
			}
			if(mGameState == Game_Running) {
				time += 1;
				eattack();
				if(time % 500 == 0) {
					score += 1;
				}
				enemyfly.subT();
				if(enemyfly.beAttack(bullet) == 1) {
					score += Constant.Reward;
				}
				if(userfly.beAttack(bullet) == 1) {
					mGameState = Game_Over;
				}
				if(enemyfly.getTime() < 0) {
					enemyfly.setEnemyFly(Re(re.nextInt()));
				}
			}
			enemyfly.draw(buf);
			
			top.draw(buf, score);
			if(mGameState == Game_Over) {
				scorecounter.draw(buf, score);
			}
		}
		

		g.drawImage(bufImg, 0,0, null);
	}
	
	public int Re(int r) {
		r = Math.abs(r) % (500 / Constant.delta);
		return (50 + Constant.delta * r);
	}
}
